# -*- coding:utf-8 -*-
import hashlib
import random

# Merkle树
def list_hashing(self,data_list):
    # 对数据列表进行哈希处理
    result_hash_list = list()
    for data in data_list:
        sha_256 = hashlib.sha256()
        sha_256.update(data.encode('utf-8'))
        result_hash_list.append(sha_256.hexdigest())
    return result_hash_list                                         #11111,首行缩进
    
def catenate_hash(self,data1,data2):
    # 对两个数据进行哈希处理
    sha_256 = hashlib.sha256()
    sha_256.update(data1.encode('utf-8'))
    sha_256.update(data2.encode('utf-8'))
    return sha_256.hexdigest()

class MerkleTree:
    def __init__(self, data_list):
        self.data_list = data_list #  初始化Merkle树，传入数据列表
        self._merkle_tree = dict()
        self.hash_list = self.list_hashing(data_list)
        (self.hash_list, self.layer_length) = self.generate(self.hash_list) #  生成Merkle树
        self._merkle_root=self.hash_list["layer_{}".format(len(self.hash_list) - 1)] #  获取Merkle根
        
        def generate(self, hash_list):
            # 生成Merkle树
            isOdd = True
            if len(data_list) % 2 == 0:
                isOdd = False
                pair_num = int(len(data_list) / 2)
                mt = dict()
                layer_count = 0
                layer_list = list()
                for i in range(pair_num):
                    layer_list.append(catenate_hash(hash_list[i], hash_list[i + 1]))
                mt["layer_{}".format(layer_count)] = layer_list
                while len(layer_list) > 1 or layer_count == 0:
                    if layer_count == 0:
                        layer_list = data_list
                    mt["layer_{}".format(layer_count)] = layer_list
                    layer_count += 1
                    if len(layer_list) == 1:
                        break
                    next_layer_list = list()
                    for i in range(pair_num):
                        next_layer_list.append(self.catenate_hash(layer_list[i], layer_list[i + 1]))
                    if isOdd == True:
                        next_layer_list.append(self.catenate_hash(layer_list[-1], layer_list[-1]))
                    layer_list = next_layer_list
                    isOdd = True
                    if len(layer_list) % 2 == 0:
                        isOdd = False
                        pair_num = int(len(layer_list) / 2)
                return (mt, layer_count)
            print("【Merkle树测试】")
            data_count = random.randint(8,20)
            data_list = list()
            for i in range(data_count):
                data.append("交易_{}".format(random.randint(0,200)))
                print("本区块中原始共{}个交易数据：".format(len(data)))
                print(data)
                mt = MerkleTree(data)
                print("Merkle树为:".mt.hash_list)
                layer_count = len(mt.hash_list)
                print("Merkle树层数为:{}".format(layer_count))
                print("Merkle各层节点数为:",mt.layer_length)
                print("Merkle树的Top Hash节点值:{}".format(mt.hash_list["layer_{}".format(str(layer_count - 1))]))

                # 测试代码
data_list = ["交易_{}".format(i) for i in range(10)]
merkle_tree = MerkleTree(data_list)